#include "pagerenderer.h"
#include "nextgen_placeholder.h"
#include "dpicalculationservice.h"
#include "margincalculationservice.h"
#include <QPainter>
#include <QDebug>
#include <QVector>
#include <QRect>
PageRenderer::PageRenderer(QObject *parent)
    : QObject(parent)
    , m_settings(nullptr)
{
}
void PageRenderer::setRenderSettings(const ProcessingSettings* settings)
{
    m_settings = settings;
    if (settings) {
    }
}
int PageRenderer::getEffectiveMarginSize() const
{
    if (!m_settings) {
        return DEFAULT_MARGIN_SIZE;  // 向后兼容
    }
    // 使用统一的边距计算服务
    double avgMarginMM = MarginCalculationService::calculateAverageMargin(m_settings->margins);
    if (avgMarginMM <= 0.0) {
        return 0;  // 真正的零边距
    }
    // 使用统一的DPI计算服务
    double currentDPI = DPICalculationService::getStandardDPI(m_settings->standardDPI);
    int marginPx = DPICalculationService::mmToPixels(avgMarginMM, currentDPI);
    return marginPx;
}
int PageRenderer::getEffectiveColumnSpacing() const
{
    // 列间距保持固定，不受边距设置影响
    return COLUMN_SPACING;
}
QSize PageRenderer::getEffectiveA4Size() const
{
    if (!m_settings) {
        // 向后兼容：使用固定的150 DPI A4尺寸
        return QSize(A4_WIDTH, A4_HEIGHT);
    }
    // 使用统一的DPI计算服务
    double currentDPI = DPICalculationService::getStandardDPI(m_settings->standardDPI);
    int width = DPICalculationService::calculateA4Width(currentDPI);
    int height = DPICalculationService::calculateA4Height(currentDPI);
    return QSize(width, height);
}
QList<QImage> PageRenderer::rearrangePagesForColumns(const QList<QImage>& originalPages, LayoutMode mode)
{
    if (originalPages.isEmpty()) {
        return originalPages;
    }
    switch (mode) {
        case LayoutMode::SingleColumn:
            // 单栏：直接返回原始页面
            return originalPages;
        case LayoutMode::TwoColumns:
            return rearrangeForTwoColumns(originalPages);
        case LayoutMode::ThreeColumns:
            return rearrangeForThreeColumns(originalPages);
        default:
            return originalPages;
    }
}
QList<QImage> PageRenderer::rearrangeForTwoColumns(const QList<QImage>& originalPages)
{
    return rearrangePagesInColumns(originalPages, 2, 2); // 2列，每列最多2张
}
QList<QImage> PageRenderer::rearrangeForThreeColumns(const QList<QImage>& originalPages)
{
    return rearrangePagesInColumns(originalPages, 3, 3); // 3列，每列最多3张
}
QList<QImage> PageRenderer::rearrangePagesInColumns(const QList<QImage>& originalPages, int columns, int maxPagesPerColumn)
{
    QList<QImage> result;
    if (originalPages.isEmpty() || columns <= 0 || maxPagesPerColumn <= 0) {
        return result;
    }
    int totalPages = originalPages.size();
    int pagesPerResultPage = columns * maxPagesPerColumn;
    int resultPages = (totalPages + pagesPerResultPage - 1) / pagesPerResultPage; // 向上取整
    // 统计原始页面中已加载的页面数量
    int loadedPages = 0;
    for (int i = 0; i < totalPages; ++i) {
        const QImage& img = originalPages[i];
        if (!img.isNull() && !NextGenPlaceholder::isPlaceholder(img)) {
            loadedPages++;
        }
    }
    // 为每个结果页生成组合页面
    for (int resultPageIndex = 0; resultPageIndex < resultPages; ++resultPageIndex) {
        // 为每个结果页收集页面
        QList<QList<QImage>> columnImages(columns);
        QList<int> columnImageWidths(columns);
        int startPageIndex = resultPageIndex * pagesPerResultPage;
        // 计算每列的图片
        for (int col = 0; col < columns; col++) {
            QList<QImage> columnPages;
            int maxWidth = 0;
            for (int row = 0; row < maxPagesPerColumn; row++) {
                int pageIndex = startPageIndex + col * maxPagesPerColumn + row;
                if (pageIndex < totalPages) {
                    QImage page = originalPages[pageIndex];
                    columnPages.append(page);
                    if (!page.isNull()) {
                        maxWidth = qMax(maxWidth, page.width());
                    }
                }
            }
            columnImages[col] = columnPages;
            columnImageWidths[col] = maxWidth > 0 ? maxWidth : 800; // 默认宽度
        }
        // 渲染这个组合页面
        QSize effectiveA4Size = getEffectiveA4Size();
        int effectiveMarginSize = getEffectiveMarginSize();
        int columnWidth = (effectiveA4Size.width() - 2 * effectiveMarginSize - (columns - 1) * COLUMN_SPACING) / columns;
        int availableHeight = effectiveA4Size.height() - 2 * effectiveMarginSize;
        // 生成 originalIndices: 记录此组合页内每个绘制项对应的原始页面索引（列优先顺序）
        QVector<int> originalIndices;
        originalIndices.reserve(columns * maxPagesPerColumn);
        for (int col = 0; col < columns; ++col) {
            for (int row = 0; row < maxPagesPerColumn; ++row) {
                int pageIndex = startPageIndex + col * maxPagesPerColumn + row;
                originalIndices.append(pageIndex);
            }
        }
        // 输出原始页到矩形的映射
        QHash<int, QRect> originalToRect;
        QImage layoutResult = renderVerticalFlowLayout(columnImages, columnImageWidths,
                                                      columns, columnWidth, COLUMN_SPACING,
                                                      effectiveMarginSize, effectiveMarginSize, effectiveMarginSize,
                                                      effectiveA4Size.width(), effectiveA4Size.height(), availableHeight,
                                                      &originalIndices, &originalToRect);
        // 保存映射到成员表，供高亮精准定位使用
        m_layoutRects[resultPageIndex] = originalToRect;
        result.append(layoutResult);
    }
    return result;
}
QImage PageRenderer::composeCompositePageAt(const QList<QImage>& originalPages, int compositeIndex, LayoutMode mode)
{
    // 将原始页面组合为指定模式下的一个组合页
    if (originalPages.isEmpty()) {
        return QImage();
    }
    int columns;
    int maxPagesPerColumn;
    switch (mode) {
        case LayoutMode::TwoColumns:
            columns = 2;
            maxPagesPerColumn = 2;
            break;
        case LayoutMode::ThreeColumns:
            columns = 3;
            maxPagesPerColumn = 3;
            break;
        case LayoutMode::SingleColumn:
        default:
            // 单栏模式直接返回对应页面
            if (compositeIndex >= 0 && compositeIndex < originalPages.size()) {
                return originalPages[compositeIndex];
            }
            return QImage();
    }
    int pagesPerResultPage = columns * maxPagesPerColumn;
    int startPageIndex = compositeIndex * pagesPerResultPage;
    // 收集这个组合页面的所有源页面
    QList<QList<QImage>> columnImages(columns);
    QList<int> columnImageWidths(columns);
    for (int col = 0; col < columns; col++) {
        QList<QImage> columnPages;
        int maxWidth = 0;
        for (int row = 0; row < maxPagesPerColumn; row++) {
            int pageIndex = startPageIndex + col * maxPagesPerColumn + row;
            if (pageIndex < originalPages.size()) {
                QImage page = originalPages[pageIndex];
                columnPages.append(page);
                if (!page.isNull()) {
                    maxWidth = qMax(maxWidth, page.width());
                }
            }
        }
        columnImages[col] = columnPages;
        columnImageWidths[col] = maxWidth > 0 ? maxWidth : 800;
    }
    // 渲染组合页面
    QSize effectiveA4Size = getEffectiveA4Size();
    int effectiveMarginSize = getEffectiveMarginSize();
    int columnWidth = (effectiveA4Size.width() - 2 * effectiveMarginSize - (columns - 1) * COLUMN_SPACING) / columns;
    int availableHeight = effectiveA4Size.height() - 2 * effectiveMarginSize;
    QImage result = renderVerticalFlowLayout(columnImages, columnImageWidths,
                                           columns, columnWidth, COLUMN_SPACING,
                                           effectiveMarginSize, effectiveMarginSize, effectiveMarginSize,
                                           effectiveA4Size.width(), effectiveA4Size.height(), availableHeight);
    return result;
}
PageRenderer::CompositeLayout PageRenderer::rearrangeWithLayout(const QList<QImage>& originalPages,
                                                               LayoutMode mode)
{
    CompositeLayout out;
    if (originalPages.isEmpty()) return out;
    // 清空并重排
    clearLayoutRects();
    out.pages = rearrangePagesForColumns(originalPages, mode);
    out.layoutRects = m_layoutRects; // 拷贝当前布局映射
    return out;
}
QImage PageRenderer::renderVerticalFlowLayout(const QList<QList<QImage>>& columnImages,
                                            const QList<int>& columnImageWidths,
                                            int columns, int columnWidth, int columnSpacing,
                                            int marginTop, int marginLeft, int marginBottom,
                                            int a4Width, int a4Height, int availableHeight,
                                            const QVector<int>* originalIndices,
                                            QHash<int, QRect>* outOriginalToRect)
{
    // 计算高亮矩形（使用紧密内容区域，精确覆盖页面内容）
    QHash<int, QRect> calcMap;
    QHash<int, QRect>* mapOut = outOriginalToRect ? outOriginalToRect : &calcMap;
    QVector<QRect> drawRects = computeVerticalFlowLayout(columnImages,
                                                         columns, columnWidth, columnSpacing,
                                                         marginTop, marginLeft, marginBottom,
                                                         a4Width, a4Height, availableHeight,
                                                         originalIndices, mapOut, false);
    // 将列优先图像展平与矩形对齐
    QVector<QImage> flatImages;
    for (int col = 0; col < columns; ++col) {
        if (col >= columnImages.size()) break;
        for (int i = 0; i < columnImages[col].size(); ++i) {
            flatImages.append(columnImages[col][i]);
        }
    }
    // 创建A4画布
    QImage combinedPage(a4Width, a4Height, QImage::Format_RGB32);
    combinedPage.fill(QColor(255, 255, 255));
    QPainter painter(&combinedPage);
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
    int n = qMin(drawRects.size(), flatImages.size());
    for (int k = 0; k < n; ++k) {
        const QRect& r = drawRects[k];
        const QImage& page = flatImages[k];
        if (page.isNull()) {
            drawBeautifulPlaceholder(&painter, r.size(), k, r.x(), r.y());
            continue;
        }
        if (page.size() == r.size()) {
            painter.drawImage(r.topLeft(), page);
        } else {
            QImage scaled = page.scaled(r.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
            painter.drawImage(r.topLeft(), scaled);
        }
    }
    painter.end();
    return combinedPage;
}
QRect PageRenderer::getOriginalRectInComposite(int compositeIndex, int originalPageIndex) const
{
    auto pageIt = m_layoutRects.find(compositeIndex);
    if (pageIt == m_layoutRects.end()) return QRect();
    const QHash<int, QRect>& map = pageIt.value();
    auto it = map.find(originalPageIndex);
    return it == map.end() ? QRect() : it.value();
}
void PageRenderer::clearLayoutRects()
{
    m_layoutRects.clear();
}
void PageRenderer::drawBeautifulPlaceholder(QPainter* painter, const QSize& size, int pageIndex, int x, int y)
{
    // 使用NextGenPlaceholder绘制美观的占位符
    QImage placeholder = NextGenPlaceholder::create(size, NextGenPlaceholder::LOADING, QString("页面 %1").arg(pageIndex + 1));
    painter->drawImage(x, y, placeholder);
}
int PageRenderer::pagesPerComposite(LayoutMode mode) const
{
    switch (mode) {
        case LayoutMode::TwoColumns:
            return 4; // 2列 × 2行
        case LayoutMode::ThreeColumns:
            return 9; // 3列 × 3行
        case LayoutMode::SingleColumn:
        default:
            return 1; // 单栏每页一个
    }
}
QVector<QRect> PageRenderer::computeVerticalFlowLayout(const QList<QList<QImage>>& columnImages,
    int columns, int columnWidth, int columnSpacing,
    int marginTop, int marginLeft, int marginBottom,
    int a4Width, int a4Height, int availableHeight,
    const QVector<int>* originalIndices,
    QHash<int, QRect>* outOriginalToRect,
    bool useLogicalAllocation) const
{
QVector<QRect> resultRects;
resultRects.reserve(columns * 8); // 预估
// 计算统一的行数（多列布局中每列应该有相同的行数）
int maxRowsPerColumn = 0;
for (int col = 0; col < columns && col < columnImages.size(); col++) {
maxRowsPerColumn = qMax(maxRowsPerColumn, columnImages[col].size());
}
// 计算每行的逻辑分配高度
int logicalSlotHeight = maxRowsPerColumn > 0 ? availableHeight / maxRowsPerColumn : availableHeight;
int seq = 0;
for (int col = 0; col < columns; col++) {
if (col >= columnImages.size()) break;
int currentY = marginTop;
int colX = marginLeft + col * (columnWidth + columnSpacing);
for (int imgIndex = 0; imgIndex < columnImages[col].size(); imgIndex++) {
QImage page = columnImages[col][imgIndex];
if (page.isNull()) {
QSize placeholderSize(columnWidth, qMin(600, availableHeight / 4));
QRect rect;
if (useLogicalAllocation) {
// 使用逻辑分配区域：占满整个槽位，但不超出边界
int actualSlotHeight = qMin(logicalSlotHeight, availableHeight - (currentY - marginTop));
rect = QRect(colX, currentY, columnWidth, actualSlotHeight);
} else {
// 使用紧密内容区域：只占实际占位符大小
rect = QRect(colX + (columnWidth - placeholderSize.width()) / 2, currentY, placeholderSize.width(), placeholderSize.height());
}
resultRects.append(rect);
if (outOriginalToRect && originalIndices && seq < originalIndices->size()) {
int originalPageIndex = (*originalIndices)[seq];
(*outOriginalToRect)[originalPageIndex] = QRect();
}
seq++;
currentY += useLogicalAllocation ? logicalSlotHeight : (placeholderSize.height() + 10);
continue;
}
QImage scaledPage = page.scaled(columnWidth, availableHeight,
Qt::KeepAspectRatio,
Qt::SmoothTransformation);
QRect rect;
if (useLogicalAllocation) {
// 使用逻辑分配区域：占满整个槽位宽度，但不超出边界
int actualSlotHeight = qMin(logicalSlotHeight, availableHeight - (currentY - marginTop));
rect = QRect(colX, currentY, columnWidth, actualSlotHeight);
} else {
// 使用紧密内容区域：只占实际图像大小
int imgX = colX + (columnWidth - scaledPage.width()) / 2;
rect = QRect(imgX, currentY, scaledPage.width(), scaledPage.height());
}
resultRects.append(rect);
if (outOriginalToRect && originalIndices && seq < originalIndices->size()) {
int originalPageIndex = (*originalIndices)[seq];
(*outOriginalToRect)[originalPageIndex] = rect;
}
seq++;
currentY += useLogicalAllocation ? logicalSlotHeight : scaledPage.height();
}
}
return resultRects;
}